package net.erl.objects.pattern.impl;

import net.erl.objects.pattern.ErlPattern;
import net.erl.objects.pattern.EPMatchable;
import net.erl.objects.pattern.EP;
import net.erl.objects.ErlTerm;
import net.erl.objects.ErlTuple;

import java.util.Map;

/**
 * A tuple pattern.
 * Closely follows ErlListPattern.
 */
public class ErlTuplePattern extends ErlPatternBase {

    private ErlPattern[] elems;

    public ErlTuplePattern(EPMatchable... items) {
        if (items.length == 0) {
            throw new IllegalArgumentException("no elements in tuple pattern");
        }
        elems = new ErlPattern[items.length];
        for (int i = 0 ; i < items.length ; i++) {
            EPMatchable item = items[i];
            elems[i] = item instanceof ErlTerm
                    ? EP.pterm((ErlTerm) item)
                    : (ErlPattern) item;
        }
    }

    public Map<String, ErlTerm> matchAndSet(ErlTerm term, Map<String, ErlTerm> initialVars) {
        if (! (term instanceof ErlTuple)) {
            return null;
        }

        ErlTuple tuple = (ErlTuple)term;
        if (tuple.getArity() != elems.length) {
            return null;
        }

        Map<String,ErlTerm> vars = ErlPatternBase.ensureVars(initialVars);
        for (int i = 0 ; i < elems.length && vars != null; i++) {
            vars = elems[i].matchAndSet(tuple.getElement(i), vars);
        }

        return vars;
    }

}